package com.lj.luoye.lotteryticket.analysis;

import com.lj.luoye.lotteryticket.dao.LotteryBuyDao;
import com.lj.luoye.lotteryticket.dao.LotteryBuyMultiDao;
import com.lj.luoye.lotteryticket.dao.LotteryHistoryDao;
import com.lj.luoye.lotteryticket.entity.Unionlotto;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;

public class UnionlottoFromStoreAndNetAnalyzer extends UnionlottoAnalyzer{
    private LotteryHistoryDao lotteryHistoryDao;
    private UnionlottoFromNetGetter unionlottoFromNetGetter;
    private LotteryBuyDao lotteryBuyDao;
    private LotteryBuyMultiDao lotteryBuyMultiDao;

    public UnionlottoFromStoreAndNetAnalyzer(LotteryHistoryDao lotteryHistoryDao,String url,LotteryBuyDao lotteryBuyDao,LotteryBuyMultiDao lotteryBuyMultiDao) {
        this.lotteryHistoryDao=lotteryHistoryDao;
        this.unionlottoFromNetGetter=new UnionlottoFromNetGetter(url);
        this.lotteryBuyDao=lotteryBuyDao;
        this.lotteryBuyMultiDao=lotteryBuyMultiDao;
    }
    private void insertToStore(List<Unionlotto> unionlottoList){
        for(Unionlotto unionlotto:unionlottoList){
            this.lotteryHistoryDao.insert(unionlotto);
        }
    }
    private void getHistory(){
        //先从文件读取往期号码
        this.unionlottoList=this.lotteryHistoryDao.getAll();
        Collections.sort(this.unionlottoList);
        Unionlotto latest=null;
        if(this.unionlottoList.size()>0){
            latest=this.unionlottoList.get(0);
        }
        System.out.println("latest->"+latest);
        //从网络获取
        List<Unionlotto> unionlottoListTemp=this.unionlottoFromNetGetter.get(latest);
        if(latest==null){
            this.unionlottoList=unionlottoListTemp;
            insertToStore(unionlottoListTemp);
        }else {
            List<Unionlotto> unionlottoListBase = new ArrayList<Unionlotto>();
            for (Unionlotto unionlotto : unionlottoListTemp) {
                if (unionlotto.getDate().equals(latest.getDate())) {
                    break;
                }
                unionlottoListBase.add(unionlotto);
            }
            insertToStore(unionlottoListBase);
            unionlottoListBase.addAll(this.unionlottoList);
            this.unionlottoList = unionlottoListBase;
        }

        System.out.println("all size->"+this.unionlottoList.size());
    }
    public void analyze(AnalyzeCallback analyzeCallback,int count,boolean multi){
        if(multi){
            analyzeMulti(analyzeCallback,count,7,1);
        }else{
            analyze(analyzeCallback,count);
        }
    }
    public void analyze(AnalyzeCallback analyzeCallback,int count){
        getHistory();

        //预测方法1
        List<Unionlotto> result4=this.fullMaxAndMin();//两组

        //预测方法2
        List<Unionlotto> result1=this.randMaxAndMin();
        for(;this.appeared(result1);){
            result1=this.randMaxAndMin();
        }

        List<Unionlotto> result2=new ArrayList<Unionlotto>();//两组
        result2.add(new Unionlotto(0,"","追号一组", Arrays.asList(new String[]{"01","04","15","18","22","32"}),"14"));
        result2.add(new Unionlotto(0,"","追号二组", Arrays.asList(new String[]{"16","19","23","25","30","33"}),"08"));

        //预测方法3
        List<Unionlotto> result3=this.sumOneByOne();
        for(;this.appeared(result3);){
            result3=this.sumOneByOne();
        }
        //随机法
        List<Unionlotto> result5=this.randOne();
        for(;this.appeared(result5);){
            result5=this.randOne();
        }
        //求和
        List<Unionlotto> result6=this.sumOneByOneReal();


        //数据结果
        System.out.println("");
        System.out.println("");
        printResult(result1);
        printResult(result2);
        printResult(result3);
        printResult(result4);
        printResult(result5);
        printResult(result6);
        //结果写入文件
        List<Unionlotto> results = new ArrayList<Unionlotto>();
        results.addAll(result1);
        if(!this.appeared(result2)){
            results.addAll(result2);
        }
        results.addAll(result3);
        if(!this.appeared(result4)){
            results.addAll(result4);
        }
        results.addAll(result5);
        if(!this.appeared(result6)){
            results.addAll(result6);
        }
        //补缺一组
        List<Unionlotto> result7 = this.fillVacancy(results);
        if(!this.appeared(result7)){
            results.addAll(result7);
        }

        //随机选2组
        List<Unionlotto> resultsRand = new ArrayList<Unionlotto>();
        shuffle(results);
        int preCount=2;
        if(count==1){
            preCount=1;
        }
        if(count==100){
            preCount=4;
        }
        for(int i=0;i<preCount;i++){
            resultsRand.add(results.get(i));
        }
        results=resultsRand;
        if(count<50) {
            for (int i = 0; i < count - preCount; i++) {
                //补缺一组
                List<Unionlotto> result8 = this.fillVacancy(results);
                for (; this.appeared(result8); ) {
                    result8 = this.fillVacancy(results);
                }
                results.addAll(result8);
            }
        }else{//平均分布算法
            List<Unionlotto> result8=this.average(count-preCount);
            for (; this.appeared(result8); ) {
                result8 = this.average(count-preCount);
            }
            results.addAll(result8);
        }
//        //补缺一组
//        List<Unionlotto> result8 = this.fillVacancy(results);
//        results.addAll(result8);
//        //补缺一组
//        List<Unionlotto> result9 = this.fillVacancy(results);
//        results.addAll(result9);
//        //补缺一组
//        List<Unionlotto> result10 = this.fillVacancy(results);
//        results.addAll(result10);
//        //补缺一组
//        List<Unionlotto> result11 = this.fillVacancy(results);
//        results.addAll(result11);

        //计算日期
        String date=calculateDate(analyzeCallback);
        if(date==null){
            return;
        }

        //this.buysUnionlottoFileReaderWriter.write(date,results);
        //结果保存到数据库
        lotteryBuyMultiDao.deleteByDate(date);
        lotteryBuyDao.saveUnionlottos(date,results);
        analyzeCallback.callBack(new AnalyzeCallback.Result(true,0,"成功"));
    }

    private String calculateDate(AnalyzeCallback analyzeCallback){
        //计算日期
        Date now=new Date();
        Calendar cal = Calendar.getInstance();
        cal.setTime(now);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        int d=0;
        if(w>0&&w<=2){//星期2的
            d=2-w;
        }else if(w>2&&w<=4){//星期4的
            d=4-w;
        }else if(w>4){
            d=7-w;
        }
        cal.add(Calendar.DATE,d);
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String date=dateFormat.format(cal.getTime());
        if(w==0||w==2||w==4){
            cal.setTime(now);
            if(cal.get(Calendar.HOUR_OF_DAY)>=20){
                System.out.println("购买时间已过");
                analyzeCallback.callBack(new AnalyzeCallback.Result(false,-1,"购买时间已过"));
                return null;
            }
        }
        return date;
    }

    @Override
    public void analyzeMulti(AnalyzeCallback analyzeCallback, int count, int redCount, int blueCount) {
        getHistory();

        List<Unionlotto> results = new ArrayList<Unionlotto>();

        if(count<8) {
            //预测方法1,最多出现和最少出现
            List<Unionlotto> result1 = this.fullMaxAndMinMulti(redCount, blueCount);//两组
            results.addAll(result1);
            //追号两组
            List<Unionlotto> result2 = this.trackMulti(redCount, blueCount);//两组
            results.addAll(result2);
        }else{
            List<Unionlotto> results11 = new ArrayList<Unionlotto>();
            //预测方法1,最多出现和最少出现
            List<Unionlotto> result1 = this.fullMaxAndMinMulti(redCount, blueCount);//两组
            results11.addAll(result1);
            //追号两组
            List<Unionlotto> result2 = this.trackMulti(redCount, blueCount);//两组
            results11.addAll(result2);
            //取1个数据
            shuffle(results11);
            results.add(results11.get(0));
        }
        //平均分布算法
        List<Unionlotto> result3 = this.averageMulti(count, redCount, blueCount);
        List<Unionlotto> result3Expand=new ArrayList<>();
        for(Unionlotto unionlotto:result3){
            List<Unionlotto> result3Exp=unionlotto.expand();
            result3Expand.addAll(result3Exp);
        }
        for (; this.appeared(result3Expand); ) {
            result3 = this.averageMulti(count, redCount, blueCount);
            result3Expand=new ArrayList<>();
            for(Unionlotto unionlotto:result3){
                List<Unionlotto> result3Exp=unionlotto.expand();
                result3Expand.addAll(result3Exp);
            }
        }
        results.addAll(result3);

        //取count个数据
        shuffle(results);
        results=results.subList(0,count);

        String date=calculateDate(analyzeCallback);
        if(date==null){
            return;
        }

        //this.buysUnionlottoFileReaderWriter.write(date,results);
        //结果保存到数据库
        lotteryBuyDao.deleteByDate(date);
        lotteryBuyMultiDao.saveUnionlottos(date,results);
        analyzeCallback.callBack(new AnalyzeCallback.Result(true,0,"成功"));
    }

    //乱序数组
    private void shuffle(List<Unionlotto> unionlottos) {
        for (int i=unionlottos.size()-1; i>=0; i--) {
            int rIndex = (int) Math.floor(Math.random()*(i+1));
            // 打印交换值
            // console.log(i, rIndex);
            Unionlotto temp = unionlottos.get(rIndex);
            unionlottos.set(rIndex,unionlottos.get(i));
            unionlottos.set(i,temp);
        }
    }
}
